﻿using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Data;
using System.Drawing;
using System.Linq;
using System.Text;
using System.Windows.Forms;
using SegIdenPC.Entidad;
using SegIdenPC.Herramientas;
using log4net;
using GS1.Utilitario;
using System.Drawing.Imaging;
using System.Configuration;

namespace SegIdenPC.Formularios
{
    public partial class frmBuscarProducto : Form
    {
        #region --- Variables y Propiedades ---
        private static readonly ILog log = LogManager.GetLogger(typeof(frmMantProducto));

        private const string TITULO = "Busqueda de Productos";

        private const string FORMATO_TOTAL_ENCONTRADOS = "Total productos encontrados: {0}";

        public Producto productoActual { get; set; }

        private Nivel niveles = null;

        public bool formularioBusqueda { get; set; }

        private string ESTADO = "A";
        #endregion

        #region --- Constructor ---
        public frmBuscarProducto()
        {
            InitializeComponent();
        }
        #endregion

        #region --- Eventos Formulario ---
        private void frmBuscarProducto_Load(object sender, EventArgs e)
        {
            cargarFormulario();
        }

        private void frmBuscarProducto_FormClosing(object sender, FormClosingEventArgs e)
        {
            
        }

        private void cboCriterioNivelProducto_SelectedIndexChanged(object sender, EventArgs e)
        {
            seleccionNivelesBusqueda();
        }

        private void btnBuscar_Click(object sender, EventArgs e)
        {
            buscar();
        }

        private void dgvListado_CellDoubleClick(object sender, DataGridViewCellEventArgs e)
        {
            seleccionarProducto();
        }

        #endregion

        #region --- Metodos Propios ---
        
        private void cargarFormulario()
        {
            try
            {
                Cursor.Current = Cursors.WaitCursor;

                // Estableciendo a 0 el texto del total de registros encontrados.
                this.lblTotalRegistros.Text = string.Format(FORMATO_TOTAL_ENCONTRADOS, 0);

                // Ejecutar carga del combo Niveles
                cargarNiveles();

            }
            catch (Exception ex)
            {
                log.Error(ex.Message, ex);
                Libreria.MensajeError(ex, TITULO);
            }
            finally
            {
                Cursor.Current = Cursors.Default;
            }
        }

        private void cargarNiveles()
        {
            Operacion operacion = null;
            string contenidoXML = string.Empty;

            // Estableciendo operacion a ser enviada al Servicio REST
            operacion = new Operacion();
            operacion.numero = Constantes.OPERACION_LISTAR_NIVELES;

            // Instanciando y ejecutando llamada al ServicioREST
            ConexionREST conexionREST = new ConexionREST();
            contenidoXML = conexionREST.ejecutarOperacion(operacion);

            // Obteniendo Objeto de Error
            OperacionError operacionError = contenidoXML.DeserializarTo<OperacionError>();

            // Validar si hay error
            if (operacionError != null)
            {
                Libreria.ShowMessageboxError(operacionError.descripcion);
                return;
            }

            // Obteniendo Objeto de Nivel
            this.niveles = contenidoXML.DeserializarTo<Nivel>();

            
            // Creando listado para nivel de producto para busqueda
            ListaNivelProducto listaNivelProducto = new ListaNivelProducto();
            listaNivelProducto.add(new NivelProducto { codigo = Constantes.CODIGO_SELECCIONE, descripcion = Constantes.DESCRIPCION_SELECCIONE });

            foreach (NivelProducto nivelProducto in this.niveles.listaNivelProducto.lista)
            {
                listaNivelProducto.add(new NivelProducto { codigo = nivelProducto.codigo, descripcion = nivelProducto.descripcion });
            }

            // Estableciendo listado de nivel de producto para busqueda
            this.cboCriterioNivelProducto.DataSource = listaNivelProducto.lista;
            this.cboCriterioNivelProducto.ValueMember = Constantes.GENERAL_CODIGO;
            this.cboCriterioNivelProducto.DisplayMember = Constantes.GENERAL_DESCRIPCION;
            this.cboCriterioNivelProducto.SelectedIndex = 0;
        }

        private void buscar()
        {
            try
            {
                if (validarEntradaBusqueda()) { return; }

                // Listar productos con el criterio y el valor ingresado
                listarProductos();

                // Estableciendo focus
                this.btnBuscar.Focus();
            }
            catch (Exception ex)
            {
                log.Error(ex.Message, ex);
                Libreria.MensajeError(ex, TITULO);
            }
        }

        private void listarProductos()
        {
            Operacion operacion = null;
            string contenidoXML = string.Empty;

            // Estableciendo operacion a ser enviada al Servicio REST
            operacion = new Operacion();
            operacion.numero = Constantes.OPERACION_LISTAR_PRODUCTOS;

            operacion.producto = new Producto();

            operacion.producto.nivelProducto = new NivelProducto();
            operacion.producto.nivelProducto.codigo = this.cboCriterioNivelProducto.SelectedValue.ToString().Equals(Constantes.CODIGO_SELECCIONE) ?
                                                                    Constantes.VALOR_CERO :
                                                                    this.cboCriterioNivelProducto.SelectedValue.ToString();

            operacion.producto.nivelTipo = new NivelTipo();
            operacion.producto.nivelTipo.codigo = this.cboCriterioNivelTipo.SelectedValue.ToString().Equals(Constantes.CODIGO_SELECCIONE) ?
                                                                    Constantes.VALOR_CERO :
                                                                    this.cboCriterioNivelTipo.SelectedValue.ToString();

            operacion.producto.nivelMaterial = new NivelMaterial();
            operacion.producto.nivelMaterial.codigo = this.cboCriterioNivelMaterial.SelectedValue.ToString().Equals(Constantes.CODIGO_SELECCIONE) ?
                                                                    Constantes.VALOR_CERO :
                                                                    this.cboCriterioNivelMaterial.SelectedValue.ToString();

            operacion.producto.nivelColor = new NivelColor();
            operacion.producto.nivelColor.codigo = this.cboCriterioNivelColor.SelectedValue.ToString().Equals(Constantes.CODIGO_SELECCIONE) ?
                                                                    Constantes.VALOR_CERO :
                                                                    this.cboCriterioNivelColor.SelectedValue.ToString();

            operacion.producto.codProductoProveedor = this.txtCriterioCodProductoProv.Text;
            operacion.producto.descripcion = this.txtDescripcionBusqueda.Text;
            operacion.producto.unionProducto = "N";
            operacion.producto.estado = this.ESTADO;

            // Instanciando y ejecutando llamada al ServicioREST
            ConexionREST conexionREST = new ConexionREST();
            contenidoXML = conexionREST.ejecutarOperacion(operacion);

            // Obteniendo Objeto de Error
            OperacionError operacionError = contenidoXML.DeserializarTo<OperacionError>();

            // Validar si hay error
            if (operacionError != null)
            {
                Libreria.ShowMessageboxError(operacionError.descripcion);
                return;
            }

            // Obteniendo Objeto de ListaProducto
            ListaProducto listaProducto = contenidoXML.DeserializarTo<ListaProducto>();

            // Mostrar el total de registros encontrados
            this.lblTotalRegistros.Text = string.Format(FORMATO_TOTAL_ENCONTRADOS, listaProducto.lista.Count);

            // Se establece propiedad para evitar que genere nuevas columnas que no estan mapeadas en la grilla
            this.dgvListado.AutoGenerateColumns = false;

            // Se establece la fuente de datos de la grilla
            this.dgvListado.DataSource = listaProducto.lista;

            // Colorear grilla deacuerdo a criterios
            pintarGrilla();
        }

        private void pintarGrilla()
        {
            ListPersonalizada<Producto> listaProductos = null;
            listaProductos = (ListPersonalizada<Producto>)this.dgvListado.DataSource;

            if (listaProductos != null)
            {
                for (int i = 0; i < listaProductos.Count; i++)
                {
                    var producto = listaProductos[i];

                    producto.estado = producto.estado.Equals(Constantes.ESTADO_CODIGO_INACTIVO) ? Constantes.ESTADO_DESCRIPCION_INACTIVO : Constantes.ESTADO_DESCRIPCION_ACTIVO;

                    if (producto.estado == Constantes.ESTADO_DESCRIPCION_INACTIVO)
                    {
                        this.dgvListado.Rows[i].DefaultCellStyle.BackColor = Color.FromArgb(255, 128, 128);
                    }
                }
            }
        }

        private bool validarEntradaBusqueda()
        {
            this.txtCriterioCodProductoProv.Text = this.txtCriterioCodProductoProv.Text.Trim();

            if (this.cboCriterioNivelProducto.SelectedValue.ToString().Equals(Constantes.CODIGO_SELECCIONE) &&
                  this.txtCriterioCodProductoProv.Text.Equals(string.Empty)&&
                this.txtDescripcionBusqueda.Text.Equals(string.Empty))
            {
                Libreria.CampoNecesario(this.cboCriterioNivelProducto, "Debe ingresar o selecionar los filtros de busqueda");
                return true;
            }

            if (!this.txtCriterioCodProductoProv.Text.Equals(string.Empty) &&
                  this.txtCriterioCodProductoProv.TextLength < 3)
            {
                Libreria.CampoNecesario(this.txtCriterioCodProductoProv, "Debe ingresar por lo menos 3 caracteres para realizar la busqueda");
                return true;
            }

            return false;
        }

        private void seleccionNivelesBusqueda()
        {
            string codigoNivelProducto = string.Empty;

            if (this.cboCriterioNivelProducto.SelectedValue is string)
            {
                codigoNivelProducto = this.cboCriterioNivelProducto.SelectedValue.ToString();
            }
            else
            {
                codigoNivelProducto = ((NivelProducto)this.cboCriterioNivelProducto.SelectedValue).codigo;
            }

            List<NivelTipo> listaNivelTipo = this.niveles.listaNivelTipo.lista;
            List<NivelMaterial> listaNivelMaterial = this.niveles.listaNivelMaterial.lista;
            List<NivelColor> listaNivelColor = this.niveles.listaNivelColor.lista;

            List<NivelTipo> listaSeleccionNivelTipo = new List<NivelTipo>();
            listaSeleccionNivelTipo.Add(new NivelTipo { codigo = Constantes.CODIGO_SELECCIONE, descripcion = Constantes.DESCRIPCION_SELECCIONE });

            List<NivelMaterial> listaSeleccionNivelMaterial = new List<NivelMaterial>();
            listaSeleccionNivelMaterial.Add(new NivelMaterial { codigo = Constantes.CODIGO_SELECCIONE, descripcion = Constantes.DESCRIPCION_SELECCIONE });

            List<NivelColor> listaSeleccionNivelColor = new List<NivelColor>();
            listaSeleccionNivelColor.Add(new NivelColor { codigo = Constantes.CODIGO_SELECCIONE, descripcion = Constantes.DESCRIPCION_SELECCIONE });

            var listaTipo = (from item in listaSeleccionNivelTipo
                             select item).
                            Union
                            (from itemTipo in listaNivelTipo
                             where itemTipo.codNivelProducto == codigoNivelProducto
                             select itemTipo);

            var listaMaterial = (from item in listaSeleccionNivelMaterial
                                 select item).
                                Union
                                (from itemMaterial in listaNivelMaterial
                                 where itemMaterial.codNivelProducto == codigoNivelProducto
                                 select itemMaterial);

            var listaColor = (from item in listaSeleccionNivelColor
                              select item).
                             Union
                             (from itemColor in listaNivelColor
                              where itemColor.codNivelProducto == codigoNivelProducto
                              select itemColor);

            this.cboCriterioNivelTipo.DataSource = listaTipo.ToList<NivelTipo>();
            this.cboCriterioNivelTipo.ValueMember = Constantes.GENERAL_CODIGO;
            this.cboCriterioNivelTipo.DisplayMember = Constantes.GENERAL_DESCRIPCION;

            this.cboCriterioNivelMaterial.DataSource = listaMaterial.ToList<NivelMaterial>();
            this.cboCriterioNivelMaterial.ValueMember = Constantes.GENERAL_CODIGO;
            this.cboCriterioNivelMaterial.DisplayMember = Constantes.GENERAL_DESCRIPCION;

            this.cboCriterioNivelColor.DataSource = listaColor.ToList<NivelColor>();
            this.cboCriterioNivelColor.ValueMember = Constantes.GENERAL_CODIGO;
            this.cboCriterioNivelColor.DisplayMember = Constantes.GENERAL_DESCRIPCION;
        }

        private void seleccionarProducto()
        {
            
                // Valida si seleccione algun producto
                if (this.dgvListado.CurrentRow != null && this.dgvListado.CurrentRow.Index > -1)
                {
                    ListPersonalizada<Producto> listaProducto = (ListPersonalizada<Producto>)this.dgvListado.DataSource;
                    this.productoActual = listaProducto[this.dgvListado.CurrentRow.Index];

                    this.DialogResult = DialogResult.OK;
                }
            
        }

        private void salir()
        {
           
                this.DialogResult = DialogResult.Cancel;
           
        }

        #endregion

        private void txtDescripcionBusqueda_TextChanged(object sender, EventArgs e)
        {

        }
    }
}
